package com.abe.libfitness.utils;

import androidx.annotation.IntDef;

import com.abe.libcore.utils.CommonUtils;
import com.abe.libcore.utils.DailyLogUtils;
import com.abe.libfitness.entity.DataEntity;
import com.google.gson.Gson;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Date;

public class ProtocolV3Utils {
    public static final int SerialPortDefault = 100;//1000ms

    public static final byte EMPTY = 0x00;
    public static final byte ADDRESS = (byte) 0xaa;//地址
    //协议码
    public static final byte TYPE_MOTOR = 0x11;//电机控制（启动、停止）
    public static final byte TYPE_POWER = 0x12;//力量设置
    public static final byte TYPE_DATA = 0x21;//数据接收
    //电机状态
    public static final int USR_IDLE = 0;
    public static final int USR_INIT = 1;
    public static final int USR_START = 2;
    public static final int USR_FIND_ZERO = 3;
    public static final int USR_RUN = 4;
    public static final int USR_STOP = 5;
    public static final int USR_WAIT = 6;
    public static final int USR_FAULT = 7;

    //电机启动或者停止
    public static byte[] motorAction(boolean start) {
        byte action;
        if (start) {
            action = 0x01;
        } else {
            action = 0x00;
        }
        byte[] command = crc(new byte[]{ADDRESS, TYPE_MOTOR, action, EMPTY});
        CommonUtils.INSTANCE.log("*************" + new Gson().toJson(command));
        return command;
    }

    //number :0-150
    public static byte[] writePower(int number) {
        if (number > 150) number = 150;
        if (number < 0) number = 0;
        byte[] command = crc(new byte[]{ADDRESS, TYPE_POWER, EMPTY, intToByte(number), EMPTY});
        CommonUtils.INSTANCE.log("*************" + new Gson().toJson(command));
        return command;
    }

    public static DataEntity parse(byte[] buffer) {
        DataEntity dataEntity = new DataEntity();
        dataEntity.setMotorStatus(byte2Int(buffer[2]));
        int distance = byte2Int(buffer[3]) * 256 + byte2Int(buffer[4]);
        dataEntity.setDistance(distance);
        int power = byte2Int(buffer[5]) * 256 + byte2Int(buffer[6]);
        dataEntity.setPower(power);
        return dataEntity;
    }


    public static void saveLocalDailyLog(String message) {
        DailyLogUtils.INSTANCE.saveLocalDailyLog(new Date(), message, ConstantFitness.LOG_SERIAL_PATH);
    }

    public static int crcSum(byte[] data) {
        int size = data.length - 1;
        int mSum = 0;
        for (int i = 0; i < size; i++) {
            mSum += data[i];
        }
        mSum = ~mSum;
        return mSum;
    }

    public static byte[] crc(byte[] data) {
        int size = data.length - 1;
        int mSum = crcSum(data);
        data[size] = (byte) (0xff & mSum);
        return data;
    }

    public static boolean isReceiveData(byte[] data) {
        return data != null && data.length > 1 && TYPE_DATA == data[1];
    }

    public static boolean verification(byte[] data) {
        int mSum = crcSum(data);
        byte v = (byte) (0xff & mSum);
        return v == data[data.length - 1];
    }

    //byte 与 int 的相互转换
    public static byte intToByte(int x) {
        return (byte) x;
    }

    public static int byte2Int(byte b) {
        return (int) (b & 0xff);
    }

    public static short getUint8(short s) {
        return (short) (s & 0x00ff);
    }

    public static int getUint16(int i) {
        return i & 0x0000ffff;
    }

    public static long getUint32(long l) {
        return l & 0x00000000ffffffff;
    }

    @IntDef({USR_IDLE, USR_INIT, USR_START, USR_FIND_ZERO, USR_RUN, USR_STOP, USR_WAIT, USR_FAULT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface MotorStatus {

    }
}